# 函数作为返回值:高阶函数除了可以接受函数作为参数外，还可以把函数作为结果值返回。
# 求和通常写法：
def calc_sum(*args):
    ax = 0
    for n in args:
        ax = ax+n
    return ax
print(calc_sum(12, 23, 34, 24, 26, 28, 10))
# 返回求和的函数写法
def lazy_sum(*args):
    def sum():
        ax = 0
        for n in args:
            ax = ax+n
        return ax
    return sum
f = lazy_sum(12, 23, 34, 24, 26, 28, 10)
print(f)  # 调用lazy_sum()时，返回的并不是求和结果，而是求和函数：
print(f())  # 调用函数f时，才真正计算求和的结果：
#注意一点，当我们调用lazy_sum()时，每次调用都会返回一个新的函数，即使传入相同的参数：
f1=lazy_sum(1,2,3,4)
f2=lazy_sum(1,2,3,4)
print(f1==f2)

#闭包：Closure。在函数lazy_sum中又定义了函数sum，并且，内部函数sum可以引用外部函数lazy_sum的参数和局部变量，当lazy_sum返回函数sum时，相关参数和变量都保存在返回的函数中，这种称为“闭包
##返回闭包时牢记一点：返回函数不要引用任何循环变量，或者后续会发生变化的变量。
##缺点是代码较长，可利用lambda函数缩短代码。
#返回一个函数时，牢记该函数并未执行，返回函数中不要引用任何可能会变化的变量。
#练习：利用闭包返回一个计数器函数，每次调用它返回递增整数：
def createCounter():
    s=[0]
    def counter():
        s[0]=s[0]+1
        return s[0]
    return counter
# 测试:
counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('测试通过!')
else:
    print('测试失败!')